# signals.py
import json
from datetime import timedelta

import pytz
from django.db.models.signals import post_save, pre_delete
from django.dispatch import receiver
from django_celery_beat.models import CrontabSchedule, PeriodicTask

from .models import MemberTraining
from .tasks import check_member_training


@receiver(post_save, sender=MemberTraining)
def schedule_training_check(sender, instance, created, **kwargs):
    if created:
        if instance.training_type == 1:  # 单次训练
            end_time = instance.end_time.astimezone(pytz.timezone('Asia/Shanghai'))
            execute_time = end_time + timedelta(seconds=1)
            execute_time_utc = execute_time.astimezone(pytz.UTC)  # 转换为 UTC 时间
            task = check_member_training.apply_async((instance.id,), eta=execute_time_utc)
            instance.tasks_id = json.dumps([task.id])
            instance.save()
        elif instance.training_type == 0:  # 定期训练
            recurrence_days = json.loads(instance.recurrence_days)
            task_ids = []
            tz = pytz.timezone('Asia/Shanghai')

            start_time = instance.start_time.astimezone(tz).replace(tzinfo=None)
            end_time = instance.end_time.astimezone(tz).replace(tzinfo=None)

            for i in range(0, len(recurrence_days)):
                recurrence_days[i] = recurrence_days[i] % 7

            day_of_week = ','.join(str(day % 7) for day in recurrence_days)

            crontab_schedule, created = CrontabSchedule.objects.get_or_create(
                minute=str(end_time.minute),
                hour=str(end_time.hour),
                day_of_week=day_of_week,
                timezone='Asia/Shanghai'
            )

            task = PeriodicTask.objects.create(
                crontab=crontab_schedule,
                name=f'check_member_training_{instance.id}_{day_of_week}',
                task='check_member_training',
                args=json.dumps([instance.id]),
                start_time=start_time,
                expires=end_time + timedelta(days=1) - timedelta(minutes=1)
            )
            task_ids.append(task.id)
            instance.tasks_id = json.dumps(task_ids)
            instance.save()


@receiver(pre_delete, sender=MemberTraining)
def cancel_training_task(sender, instance, **kwargs):
    if instance.tasks_id:
        task_ids = json.loads(instance.tasks_id)
        if instance.training_type == 1:  # 单次训练
            for task_id in task_ids:
                # 对于 apply_async 创建的任务，使用 revoke 方法取消
                check_member_training.AsyncResult(task_id).revoke()
        elif instance.training_type == 0:  # 定期训练
            for task_id in task_ids:
                # 对于定期任务，删除 PeriodicTask
                task = PeriodicTask.objects.get(id=task_id)
                task.delete()
